<template>
  <div class="c-date-picker">
    <div class="data-change">
      <i class="icon el-icon-d-arrow-left" @click="dateChange('year','reduce')"></i>
      <i class="icon el-icon-arrow-left" @click="dateChange('month','reduce')"></i>
      <span class="time">{{year}}年{{month}}月</span>
      <i class="icon el-icon-arrow-right" @click="dateChange('month','add')"></i>
      <i class="icon el-icon-d-arrow-right" @click="dateChange('year','add')"></i>
    </div>
    <div class="week-title">
      <p v-for="(item,index) in weekGroup" :key="'week'+index">{{item}}</p>
    </div>
    <div class="day">
      <p v-for="(item,index) in calendar" :key="'day'+index" :style="{color:item.isCurrentMonth?'#000':'#bbb' }" :class="{today:item.today,selectDay:`${year}-${month}-${item.day}`===selectedDay}" @click="selectDate(item,index)">{{item.today?'今':item.day}}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    this.weekGroup = ['一', '二', '三', '四', '五', '六', '日']
    return {
      year: '',
      month: '',
      selectedDay: '',
      nowDay: '',
      calendar: []
    }
  },
  mounted() {
    const date = this.getNowDate()
    this.year = date[0]
    this.month = date[1]
    this.day = date[2]
    this.nowDay = date.join('-')
    this.getCalendar()
  },
  methods: {
    // 选中时间
    selectDate(item) {
      if (item.isCurrentMonth) {
        this.selectedDay = `${this.year}-${this.month}-${item.day}`
        this.$emit("select", this.selectedDay)
      }
    },
    /**
     * @description: 日期的切换
     * @param {String: year | month} time: 要切换的时间
     * @param {String: reduce | add} change: 时间的加减
     */
    dateChange(time, change) {
      if (change === 'reduce') {
        if (time === 'month') {
          if (this[time] == '1') {
            this[time] = 12
            this.year--
          } else {
            0
            this[time]--
          }
        } else {
          this[time]--
        }
      } else if (change === 'add') {
        if (time === 'month') {
          if (this[time] == '12') {
            this[time] = 1
            this.year++
          } else {
            this[time]++
          }
        } else {
          this[time]++
        }
      }
      this.getCalendar()
    },
    /**
     * @description: 获取当前日期
     * @return {*} [YYYY, D, M]
     */
    getNowDate() {
      return new Date().toLocaleDateString().split('/');
    },
    /**
     * @description: 获取本月最后一天 ( 如果不传年月就是当前年月 )
     * @param {String: YYYY} year: 哪一年
     * @param {String: DD} month: 哪一月
     * @return {*} 最后一天的日期
     */
    getMonthFinalDay(year, month) {
      let day = '';
      if (year == null || year == undefined || year == '') {
        year = new Date().getFullYear();
      }
      if (month == null || month == undefined || month == '') {
        month = new Date().getMonth() + 1;
      }
      day = new Date(new Date(year, month).setDate(0)).getDate();
      return day;
    },
    /**
     * @description: 获取指定的日期是周几
     * @param {String: YYYY/DD/MM} date: 指定的日期
     * @return {*} 周几
     */
    getDayOfWeek(year, month, day) {
      let weekGroup = ['7', '1', '2', '3', '4', '5', '6']
      let week = new Date(`${year}/${month}/${day}`).getDay();
      return weekGroup[week];
    },
    // 获取日历
    getCalendar() {
      this.calendar = []
      // 获取上一个月的最后一天是几号
      const previousMonthFinallyDay = this.getMonthFinalDay(this.year, this.month - 1)
      // 获取本月的第一天是周几
      const firstDayWeek = this.getDayOfWeek(this.year, this.month, '01')
      // 生成日历上个月的天数
      for (let i = firstDayWeek - 2; i >= 0; i--) {
        this.calendar.push({
          isCurrentMonth: false,
          day: previousMonthFinallyDay - i
        })
      }

      // 获取本月的最后一天
      const firstDay = this.getMonthFinalDay(this.year, this.month)
      // 生成日历本月的天数
      for (let i = 1; i <= firstDay; i++) {
        const o = {
          isCurrentMonth: true,
          day: i
        }
        if (`${this.year}-${this.month}-${i}` === this.nowDay) {
          o.today = true
        }
        this.calendar.push(o)
      }

      // 如果日历的天数刚好满周就不生成下个月的天数
      if (this.calendar.length % 7 !== 0) {
        // 获取本月的最后一天是周几
        const lastDayWeek = this.getDayOfWeek(this.year, this.month, firstDay)
        // 生成日历下个月初的天数
        for (let i = 1; i <= 7 - lastDayWeek; i++) {
          this.calendar.push({
            isCurrentMonth: false,
            day: i
          })
        }
      }
    }
  },
}
</script>

<style lang="scss" scoped>
.c-date-picker {
  width: 400px;
  background-color: #f5f8f7;
  .data-change {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 20px 0 10px;
    .icon {
      cursor: pointer;
      padding: 0 15px;
      color: #ccc;
      &:hover {
        color: #000;
      }
    }
    .time {
      padding: 0 15px;
      font-size: 16px;
    }
  }
  .week-title {
    font-size: 14px;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    place-items: center center;
    padding: 10px 0;
  }
  .day {
    font-size: 14px;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    place-items: center center;
    > p {
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 5px 0;
      width: 30px;
      height: 30px;
    }
  }
  .today {
    border: 1px solid #ccc;
    color: #fff !important;
    background-color: #02adea;
    border-radius: 5px;
  }
  .selectDay {
    color: #fff !important;
    background-color: #02acea84;
    border-radius: 5px;
  }
}
</style>